﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BaiduFanyi.Messages;
using ParkingLot.Utility.MessageHelp;

namespace BaiduFanyi
{
    public class Utilitys
    {
        public static string GetPrepertyName(string dst)
        {
            char[] words = dst.ToCharArray();

            List<char> lisResultWords = new List<char>();

            //首字母大写
            if (words.Length > 0)
            {
                words[0] = char.ToUpper(words[0]);
            }

            for (int i = 0; i < words.Length; i++)
            {
                //32是空格的意思
                if (words[i] == 32)
                {
                    if (i < words.Length - 2)
                    {
                        //第二个单词 首字母大写(如Space number 应该为SpaceNumber)
                        words[i + 1] = char.ToUpper(words[i + 1]);
                    }
                    continue;
                }

                //过滤掉非字母
                if (!char.IsLetter(words[i]))
                {
                    if (i < words.Length - 2)
                    {
                        //第二个单词 首字母大写(如Space number 应该为SpaceNumber)
                        words[i + 1] = char.ToUpper(words[i + 1]);
                    }
                    continue;
                }
                lisResultWords.Add(words[i]);
            }

            string result = new string(lisResultWords.ToArray());

            return result;
        }

        public static string GetNotifyProperty(string property, string explan, string type)
        {
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"private {type} m_{property};");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public {type} {property}");
            sbValue.AppendLine($"{{");
            sbValue.AppendLine($" get {{ return m_{property}; }}");
            sbValue.AppendLine($"set");
            sbValue.AppendLine($"{{");
            sbValue.AppendLine($" m_{property} = value;");
            sbValue.AppendLine($"  this.RaisePropertyChanged(()=> {property});");
            sbValue.AppendLine($"}}");
            sbValue.AppendLine($"}}");
            return sbValue.ToString();
        }

        public static string GetWPFNotifyProperty(string property, string explan, string type)
        {
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($" [Reactive]public {type} {property} {{ get; set; }}");
            return sbValue.ToString();
        }

        public static string GetWPFCommand(string property, string explan, string type)
        {
            type = "ICommand";
            string oldproperty = property;
            property = "Cmd" + property;
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($" [Reactive]public {type} {property} {{ get; set; }}");
            sbValue.AppendLine();

            sbValue.AppendLine($" {property}= new DeletgateCommand<object>({oldproperty});");
            sbValue.AppendLine();

            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"///<param name=\"value\"></param>");
            sbValue.AppendLine($"  private void {oldproperty}(object value)");
            sbValue.AppendLine($"{{");
            sbValue.AppendLine();
            sbValue.AppendLine($"}}");
          
            return sbValue.ToString();
        }

        public static string GetAvaloniaProperty(string property, string explan, string type)
        {
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"private {type} m_{property};");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public {type} {property}");
            sbValue.AppendLine($"{{");
            sbValue.AppendLine($" get {{ return m_{property}; }}");
            sbValue.AppendLine($"set");
            sbValue.AppendLine($"{{");
            sbValue.AppendLine($"  this.RaiseAndSetIfChanged(ref  m_{property},value);");
            sbValue.AppendLine($"}}");
            sbValue.AppendLine($"}}");
            return sbValue.ToString();
        }

        public static string GetAvaloniaStyleProperty(string property, string explan, string type,string parent)
        {
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static readonly StyledProperty<{type}> {property}Property = AvaloniaProperty.Register<{parent}, {type}>(nameof({property}));");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public {type} {property}");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"  get {{ return GetValue ({property}Property); }}");
            sbValue.AppendLine($"  set {{ SetValue ({property}Property, value); }}");
            sbValue.AppendLine("}");
            return sbValue.ToString();
        }


        public static string GetAttachedProperty(string property, string explan, string type, string parent)
        {
            string typeInstanceName = type;
            char[] chars = type.ToCharArray();
            if (char.IsUpper(chars[0]))
            {
                chars[0] = char.ToLower(chars[0]);
                typeInstanceName = new string(chars);
            }
            else
            {
                typeInstanceName = $"{type}Value";
            }

            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static readonly AttachedProperty<{type}> {property}Property = AvaloniaProperty.RegisterAttached<{parent}, Interactive, {type}>(\"{property}\");");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static void Set{property}(AvaloniaObject element, {type} {typeInstanceName})");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"   element.SetValue({property}Property, {typeInstanceName});");
            sbValue.AppendLine("}");
            sbValue.AppendLine($" public static {type} Get{property}(AvaloniaObject element)");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"    return element.GetValue({property}Property);");
            sbValue.AppendLine("}");
            return sbValue.ToString();
        }

        public static string GetBindableProperty(string property, string explan, string type,string ownerType)
        {
            StringBuilder sbValue = new StringBuilder();
            string bindablePropertyName = $"{property}Property";
            sbValue.AppendLine($"public static readonly BindableProperty {property}Property =");
            sbValue.AppendLine($"BindableProperty.Create (\"{property}\", typeof({type}), typeof({ownerType}), null);");
            sbValue.AppendLine($"public {type} {property}");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"  get {{ return (type)GetValue ({property}Property); }}");
            sbValue.AppendLine($"  set {{ SetValue ({property}Property, value); }}");
            sbValue.AppendLine("}");
            return sbValue.ToString();
        }

        public static Tuple<string, string, string> GetTuple(string property, string explanValue, string typeName, out string error)
        {
            error = "";
            try
            {
                
                bool isNullPropertyName = string.IsNullOrEmpty(property);
                bool isNullExplan = string.IsNullOrEmpty(explanValue);
                string type = "string";
                if (!string.IsNullOrEmpty(typeName))
                {
                    type = typeName;
                    if (!ProjectConfig.Instance.DictCommonClass.ContainsKey(typeName))
                    {
                        ProjectConfig.Instance.DictCommonClass.Add(typeName,0);
                        //MessageAggregator<UpdateTypeMessage>.Publish(new UpdateTypeMessage(){ TypaName = typeName });
                    }

                    ProjectConfig.Instance.DictCommonClass[typeName]++;
                    ProjectConfig.Instance.Save();


                }
                if (isNullPropertyName && isNullExplan)
                {
                    error = "没有内容";
                    return null;
                }
                string propertyName = property;
                string explan = explanValue;


                if (property.Contains("m_"))
                {
                    propertyName = property.Substring(2, property.Length - 2);
                }


                if ((!isNullPropertyName) && (!isNullExplan))
                {
                    //do Nothing
                }
                else if (isNullPropertyName)
                {
                    //属性为空 根据解释生成属性
                    TranslateResult translateResult = TranslateHelp.Translate(explanValue, TranslateType.Chines);
                    propertyName = Utilitys.GetPrepertyName(translateResult.trans_result[0].dst);
                }
                else
                {
                    //解释为空 根据解释生成属性
                    TranslateResult translateResult = TranslateHelp.Translate(property, TranslateType.Eng);
                    explan = Utilitys.GetPrepertyName(translateResult.trans_result[0].dst);
                }
                return new Tuple<string, string, string>(propertyName, explan, type);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return new Tuple<string, string, string>(property, explanValue, typeName);
            }
        }

        public static string GetWPFDependencyProperty(string property, string explan, string type, string parent)
        {
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static readonly DependencyProperty {property}Property = DependencyProperty.Register(nameof({property}),typeof({type}), typeof({parent}));");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public {type} {property}");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"  get {{ return ({type})GetValue({property}Property); }}");
            sbValue.AppendLine($"  set {{ SetValue ({property}Property, value); }}");
            sbValue.AppendLine("}");
            return sbValue.ToString();
        }

        public static string GetWPFAttachedProperty(string property, string explan, string type, string parent)
        {
            string typeInstanceName = type;
            char[] chars = type.ToCharArray();
            if (char.IsUpper(chars[0]))
            {
                chars[0] = char.ToLower(chars[0]);
                typeInstanceName = new string(chars);
            }
            else
            {
                typeInstanceName = $"{type}Value";
            }

            typeInstanceName = "value";
            StringBuilder sbValue = new StringBuilder();
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static readonly DependencyProperty {property}Property = DependencyProperty.RegisterAttached(\"{property}\",typeof({type}), typeof({parent}));");
            sbValue.AppendLine($"");
            sbValue.AppendLine($"/// <summary>");
            sbValue.AppendLine($"///{explan}");
            sbValue.AppendLine($"/// </summary>");
            sbValue.AppendLine($"public static void Set{property}(DependencyObject element, {type} {typeInstanceName})");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"   element.SetValue({property}Property, {typeInstanceName});");
            sbValue.AppendLine("}");
            sbValue.AppendLine($" public static {type} Get{property}(DependencyObject element)");
            sbValue.AppendLine("{");
            sbValue.AppendLine($"    return ({type})element.GetValue({property}Property);");
            sbValue.AppendLine("}");
            return sbValue.ToString();
        }
    }
}
